সি++ স্ট্যান্ডার্ড লাইব্রেরির Sequence Containers হলো এমন কিছু কনটেইনার, যা ডেটা সিকোয়েন্স আকারে সংরক্ষণ করে। এর মধ্যে std::vector, std::deque, এবং std::list হলো সবচেয়ে ব্যবহৃত ও জনপ্রিয় সিকোয়েন্স কনটেইনার। প্রতিটি কনটেইনারের নিজস্ব বৈশিষ্ট্য ও ব্যবহার আছে, যা নির্দিষ্ট পরিস্থিতিতে ব্যবহার করা সুবিধাজনক। নিচে এই কনটেইনারগুলো নিয়ে বিস্তারিত আলোচনা করা হলো:
১. std::vector
std::vector হলো ডাইনামিক অ্যারে যা প্রয়োজন অনুযায়ী আকার পরিবর্তন করতে সক্ষম। এটি সাধারণ অ্যারের মতোই কাজ করে, তবে এর আকার ডায়নামিকালি বাড়ানো বা ছোট করা যায়। std::vector সাধারণত যখন এলিমেন্টগুলো লিনিয়ার অ্যাক্সেস প্রয়োজন এবং অ্যারের আকার পরিবর্তনযোগ্য হতে হবে তখন ব্যবহৃত হয়।
বৈশিষ্ট্য:
- এলিমেন্টগুলো ধারাবাহিকভাবে (contiguous memory) সংরক্ষিত থাকে।
- এলিমেন্ট অ্যাক্সেস করার জন্য
O(1)সময় লাগে, যা খুবই দ্রুত। - শেষ প্রান্তে এলিমেন্ট যোগ বা মুছে ফেলা
O(1)সময়ে সম্ভব।
উদাহরণ:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4};
vec.push_back(5); // নতুন এলিমেন্ট যোগ করা
vec.pop_back(); // শেষ এলিমেন্ট মুছে ফেলা
// ভেক্টরের সব এলিমেন্ট প্রদর্শন
for (int val : vec) {
std::cout << val << " ";
}
return 0;
}কখন ব্যবহার করবেন:
- যখন এলিমেন্টগুলো ধারাবাহিক মেমোরিতে সংরক্ষণ করতে চান।
- যখন কনটেইনারের শেষ প্রান্তে এলিমেন্ট যোগ বা মুছে ফেলতে হবে।
- যখন এলিমেন্টগুলোতে এলোমেলোভাবে (random access) অ্যাক্সেস প্রয়োজন।
২. std::deque
std::deque বা "Double Ended Queue" হলো এমন একটি কনটেইনার যা উভয় প্রান্তে এলিমেন্ট যোগ ও মুছে ফেলার সুবিধা দেয়। এটি অ্যারের মতোই কাজ করে, তবে প্রয়োজন অনুযায়ী উভয় প্রান্তে ডাটা সংরক্ষণ করতে পারে।
বৈশিষ্ট্য:
- এলিমেন্ট যোগ বা মুছে ফেলা উভয় প্রান্ত থেকে করা যায়।
- এলিমেন্ট অ্যাক্সেসের সময় সাধারণত
O(1)লাগে। std::dequeডায়নামিক মেমরি ব্যবহার করে, তাই প্রয়োজনমতো আকার বাড়ানো বা কমানো যায়।
উদাহরণ:
#include <iostream>
#include <deque>
int main() {
std::deque<int> deq = {1, 2, 3};
deq.push_front(0); // সামনে নতুন এলিমেন্ট যোগ করা
deq.push_back(4); // শেষে নতুন এলিমেন্ট যোগ করা
// ডেক-এর সব এলিমেন্ট প্রদর্শন
for (int val : deq) {
std::cout << val << " ";
}
return 0;
}কখন ব্যবহার করবেন:
- যখন উভয় প্রান্ত থেকে ডেটা অ্যাক্সেস বা সংশোধনের প্রয়োজন।
- যখন এলিমেন্টগুলোতে এলোমেলোভাবে অ্যাক্সেস প্রয়োজন।
- যখন শেষ এবং শুরু থেকে দ্রুত অ্যাক্সেস দরকার, তবে মধ্যবর্তী স্থান থেকে অ্যাক্সেসের প্রয়োজন নেই।
৩. std::list
std::list হলো ডাবল লিংকড লিস্ট, যেখানে প্রতিটি নোড আগের এবং পরের নোডের সাথে লিঙ্ক থাকে। এটি সিকোয়েন্সের মাঝখানে দ্রুত ডেটা যোগ বা মুছে ফেলার জন্য অত্যন্ত কার্যকর।
বৈশিষ্ট্য:
- ডাবল লিংকড লিস্ট হিসেবে কাজ করে।
- মাঝখানে ডেটা যোগ বা মুছে ফেলা
O(1)সময়ে সম্ভব, যদি ইটরেটর দিয়ে নির্দিষ্ট অবস্থানে পৌঁছানো যায়। - এলিমেন্টগুলো ধারাবাহিক মেমোরিতে থাকে না, তাই এলোমেলো অ্যাক্সেস
O(n)সময়ে হয়।
উদাহরণ:
#include <iostream>
#include <list>
int main() {
std::list<int> lst = {1, 2, 3, 4};
lst.push_front(0); // সামনে নতুন এলিমেন্ট যোগ করা
lst.push_back(5); // শেষে নতুন এলিমেন্ট যোগ করা
lst.pop_front(); // সামনে থেকে এলিমেন্ট মুছে ফেলা
// লিস্টের সব এলিমেন্ট প্রদর্শন
for (int val : lst) {
std::cout << val << " ";
}
return 0;
}কখন ব্যবহার করবেন:
- যখন মাঝখানে এলিমেন্ট দ্রুত যোগ বা মুছে ফেলার প্রয়োজন।
- যখন কনটেইনারের আকার পরিবর্তন করতে হবে।
- যখন এলোমেলো অ্যাক্সেসের প্রয়োজন নেই এবং শুধুমাত্র ধারাবাহিকভাবে ডেটা অ্যাক্সেস করতে হবে।
সংক্ষেপে তুলনা
| বৈশিষ্ট্য | std::vector | std::deque | std::list |
|---|---|---|---|
| মেমরি অ্যারেঞ্জমেন্ট | ধারাবাহিক (contiguous) মেমরি | ডায়নামিক, ধারাবাহিক নয় | ডাবল লিংকড লিস্ট |
| এলোমেলো অ্যাক্সেস | O(1) (দ্রুত) | O(1) (দ্রুত) | O(n) (ধীর) |
| প্রান্তে অপারেশন | শেষ প্রান্তে দ্রুত | উভয় প্রান্তে দ্রুত | উভয় প্রান্তে দ্রুত |
| মাঝখানে অপারেশন | ধীর | ধীর | দ্রুত (O(1) ইটরেটরের সাথে) |
এই তিনটি সিকোয়েন্স কনটেইনার প্রতিটি নির্দিষ্ট ব্যবহারের জন্য উপযোগী। std::vector সাধারণত যখন এলোমেলো অ্যাক্সেস দরকার হয় তখন ব্যবহার করা হয়, std::deque যখন উভয় প্রান্ত থেকে অ্যাক্সেস বা পরিবর্তনের প্রয়োজন হয়, এবং std::list যখন মাঝখানে দ্রুত ডেটা পরিবর্তনের প্রয়োজন হয়।
Read more